﻿using DT.GoogleAnalytics.Metro;
using FantasyWereld.Code;
using FantasyWereld.Common;
using FantasyWereld.Data;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.ApplicationModel.Search;
using Windows.Data.Xml.Dom;
using Windows.System.Threading;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237

namespace FantasyWereld.Views
{
    /// <summary>
    /// A basic page that provides characteristics common to most applications.
    /// </summary>
    public sealed partial class MainPage : FantasyWereld.Common.LayoutAwarePage
    {
        static DateTime updateTimeRefreshDataFromWebserver = DateTime.Now;

        public static MainPage Current;
                
        public MainPage()
        {
            this.InitializeComponent();
            FadeOpacity.Begin();
            this.channelItemsViewSource.Source = NavDataSource.GetGroups("AllGroups");

            // Update ShowNew icon on groups
            if (FWDataSource.NrOfBooks != NavDataSource.GetGroup(Constants.BOOKFEED_TITLE).Count)
                NavDataSource.GetGroup(Constants.BOOKFEED_TITLE).ShowNew = true;
            if (FWDataSource.NrOfReviews != NavDataSource.GetGroup(Constants.RSSFEED_R_TITLE).Count)
                NavDataSource.GetGroup(Constants.RSSFEED_R_TITLE).ShowNew = true;
            if (FWDataSource.NrOfInterviews != NavDataSource.GetGroup(Constants.RSSFEED_IV_TITLE).Count)
                NavDataSource.GetGroup(Constants.RSSFEED_IV_TITLE).ShowNew = true;
            if (FWDataSource.NrOfGastblogs != NavDataSource.GetGroup(Constants.RSSFEED_GB_TITLE).Count)
                NavDataSource.GetGroup(Constants.RSSFEED_GB_TITLE).ShowNew = true;
            if (FWDataSource.NrOfArtikelen != NavDataSource.GetGroup(Constants.RSSFEED_AR_TITLE).Count)
                NavDataSource.GetGroup(Constants.RSSFEED_AR_TITLE).ShowNew = true;
            if (FWDataSource.NrOfSchrijven != NavDataSource.GetGroup(Constants.RSSFEED_SC_TITLE).Count)
                NavDataSource.GetGroup(Constants.RSSFEED_SC_TITLE).ShowNew = true;
            if (FWDataSource.NrOfOverigeRecensies != NavDataSource.GetGroup(Constants.RSSFEED_OR_TITLE).Count)
                NavDataSource.GetGroup(Constants.RSSFEED_OR_TITLE).ShowNew = true;
            if (FWDataSource.NrOfAuthors != NavDataSource.GetGroup(Constants.AUTHORFEED_TITLE).Count)
                NavDataSource.GetGroup(Constants.AUTHORFEED_TITLE).ShowNew = true;
            if (FWDataSource.NrOfStories != NavDataSource.GetGroup(Constants.SHORTSTORYFEED_TITLE).Count)
                NavDataSource.GetGroup(Constants.SHORTSTORYFEED_TITLE).ShowNew = true;
        }
                
        /// <summary>
        /// Invoked when a group header is clicked.
        /// </summary>
        /// <param name="sender">The Button used as a group header for the selected group.</param>
        /// <param name="e">Event data that describes how the click was initiated.</param>
        void Header_Click(object sender, RoutedEventArgs e)
        {
            // Process the RSS Feeds asynchronously when more than set hours have past
            if ((DateTime.Now - updateTimeRefreshDataFromWebserver).Hours >= Constants.UPDATE_HOURS)
            {
                FWDataSource.LoadRemoteDataAsync();

                // Reset Timer
                updateTimeRefreshDataFromWebserver = DateTime.Now;
            }

            // Determine what group the Button instance represents
            switch ((sender as FrameworkElement).DataContext.ToString())
            {
                case Constants.RSSFEED_N_TITLE:
                    {
                        BadgeUpdater.UpdateNewsItem();
                        break;
                    }
                case Constants.RSSFEED_R_TITLE:
                    {   
                        this.Frame.Navigate(typeof(GroupedItemsPage), "ReviewGroups");
                        break;
                    }
                case Constants.BOOKFEED_TITLE:
                    {
                        this.Frame.Navigate(typeof(BookOverviewPage), Constants.BOOKFEED_BD_CODE);
                        break;
                    }
                case Constants.RSSFEED_IV_TITLE:
                    {
                        this.Frame.Navigate(typeof(RSSViewPage), Constants.RSSFEED_IV_CODE);
                        break;
                    }
                case Constants.RSSFEED_GB_TITLE:
                    {
                        this.Frame.Navigate(typeof(RSSViewPage), Constants.RSSFEED_GB_CODE);
                        break;
                    }
                case Constants.RSSFEED_AR_TITLE:
                    {
                        this.Frame.Navigate(typeof(RSSViewPage), Constants.RSSFEED_AR_CODE);
                        break;
                    }
                case Constants.RSSFEED_OR_TITLE:
                    {
                        this.Frame.Navigate(typeof(RSSViewPage), Constants.RSSFEED_OR_CODE);
                        break;
                    }
                case Constants.RSSFEED_SC_TITLE:
                    {
                        this.Frame.Navigate(typeof(RSSViewPage), Constants.RSSFEED_SC_CODE);
                        break;
                    }
                case Constants.AUTHORFEED_TITLE:
                    {
                        this.Frame.Navigate(typeof(AuthorOverviewPage), Constants.AUTHORFEED_CODE);
                        break;
                    }
                case Constants.SHORTSTORYFEED_TITLE:
                    {
                        this.Frame.Navigate(typeof(RSSViewPage), Constants.SHORTSTORYFEED_CODE);
                        break;
                    }
            };
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
        protected override void SaveState(Dictionary<String, Object> pageState)
        {
        }

        /// <summary>
        /// Invoked when the OpenReviews button is clicked.
        /// </summary>
        /// <param name="sender">The Button used as a link to the reviews.</param>
        /// <param name="e">Event data that describes how the click was initiated.</param>
        void OpenReviews(object sender, RoutedEventArgs e)
        {
            // Determine what group the Button instance represents
            var group = (sender as FrameworkElement).DataContext;

            // Navigate to the appropriate destination page, configuring the new page
            // by passing required information as a navigation parameter
            this.Frame.Navigate(typeof(GroupedItemsPage), "ReviewGroups");
        }

        /// <summary>
        /// Invoked when the OpenReviews button is clicked.
        /// </summary>
        /// <param name="sender">The Button used as a link to the reviews.</param>
        /// <param name="e">Event data that describes how the click was initiated.</param>
        void OpenBookDatabase(object sender, RoutedEventArgs e)
        {
            // Determine what group the Button instance represents
            var group = (sender as FrameworkElement).DataContext;

            // Navigate to the appropriate destination page, configuring the new page
            // by passing required information as a navigation parameter
            this.Frame.Navigate(typeof(BookOverviewPage), "BD");
        }
        
        private async void OnBrowseToReviewButtonClicked(object sender, RoutedEventArgs e)
        {
            string link = BadgeUpdater.GetNewsLink();

            if (link.Contains("recensies"))
            {
                string itemId = link.Substring(link.IndexOf("recensies"));
                this.Frame.Navigate(typeof(ItemDetailPage), itemId);
            }
            else
                if (link.Contains("interviews") )
                {
                    string itemId = link.Substring(link.IndexOf("interviews"));
                    this.Frame.Navigate(typeof(RSSDetailPage), itemId);
                }
                else
                    if (link.Contains("schrijven") )
                    {
                        string itemId = link.Substring(link.IndexOf("schrijven"));
                        this.Frame.Navigate(typeof(RSSDetailPage), itemId);
                    }
                    else
                        if (link.Contains("reviews"))
                        {
                            string itemId = link.Substring(link.IndexOf("reviews"));
                            this.Frame.Navigate(typeof(RSSDetailPage), itemId);
                        }
                        else
                            if (link.Contains("gastblogs"))
                            {
                                string itemId = link.Substring(link.IndexOf("gastblogs"));
                                this.Frame.Navigate(typeof(RSSDetailPage), itemId);
                            }
                            else
                                if (link.Contains("achtergrond"))
                                {
                                    string itemId = link.Substring(link.IndexOf("achtergrond"));
                                    this.Frame.Navigate(typeof(RSSDetailPage), itemId);
                                }
                                else
                                {
                                    // Create the URI to launch from a string. 
                                    var uri = new Uri(link);

                                    // Launch the URI. 
                                    await Windows.System.Launcher.LaunchUriAsync(uri);
                                }
        }

        /// <summary>
        /// Invoked when a user wants to browse to the FantasyWereld website.
        /// </summary>
        /// <param name="sender">Sender parameter is unused</param>
        /// <param name="e">Event data parameters is unused</param>
        private async void OnBrowseToSiteButtonClicked(object sender, RoutedEventArgs e)
        {
            // Create the URI to launch from a string. 
            var uri = new Uri(Constants.WEBSITEBASE);

            // Launch the URI. 
            await Windows.System.Launcher.LaunchUriAsync(uri);
        }

        /// <summary>
        /// Invoked when a user wants to browse to the FantasyWereld forum.
        /// </summary>
        /// <param name="sender">Sender parameter is unused</param>
        /// <param name="e">Event data parameters is unused</param>
        private async void OnBrowseToForumButtonClicked(object sender, RoutedEventArgs e)
        {
            // Create the URI to launch from a string. 
            var uri = new Uri(Constants.WEBSITE_FORUM);

            // Launch the URI. 
            await Windows.System.Launcher.LaunchUriAsync(uri);
        }

        /// <summary>
        /// Invoked when a user wants to browse to the FantasyWereld facebook page.
        /// </summary>
        /// <param name="sender">Sender parameter is unused</param>
        /// <param name="e">Event data parameters is unused</param>
        private async void OnBrowseToFacebookButtonClicked(object sender, RoutedEventArgs e)
        {
            // Create the URI to launch from a string. 
            var uri = new Uri(Constants.WEBSITE_FACEBOOK);

            // Launch the URI. 
            await Windows.System.Launcher.LaunchUriAsync(uri);
        }

        private void SearchBoxEventsSuggestionsRequested(object sender, SearchBoxSuggestionsRequestedEventArgs e)
        {
            string queryText = e.QueryText;
            if (!string.IsNullOrEmpty(queryText))
            {
                SearchSuggestionCollection suggestionCollection = e.Request.SearchSuggestionCollection;

                string[] terms = FWDataSource.AllKeywords;

                foreach (var term in terms)
                {
                    if (term.StartsWith(queryText, StringComparison.CurrentCultureIgnoreCase))
                        suggestionCollection.AppendQuerySuggestion(term);
                }
            }
        }

        /// <summary>
        /// Called when query submitted in SearchBox
        /// </summary>
        /// <param name="sender">The Xaml SearchBox</param>
        /// <param name="e">Event when user submits query</param>
        private void SearchBoxEventsQuerySubmitted(object sender, SearchBoxQuerySubmittedEventArgs e)
        {
            var queryText = e.QueryText;
            if (!string.IsNullOrEmpty(queryText))
            {
                // Load books if still necessary
                FWDataSource.LoadBooks();

                // If the Window isn't already using Frame navigation, insert our own Frame
                var previousContent = Window.Current.Content;
                var frame = previousContent as Frame;

                frame.Navigate(typeof(SearchResultsPage), queryText);
                Window.Current.Content = frame;

                // Google Analytics helper
                AnalyticsHelper.Setup();

                // Ensure the current window is active
                Window.Current.Activate();
            }
        }

        private void SearchBox_GotFocus(object sender, RoutedEventArgs e)
        {
            (sender as SearchBox).Width = 250;
        }

        private void SearchBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if ((sender as SearchBox).QueryText == "")
                (sender as SearchBox).Width = 35;
        }
    }
}
